package com.hulk.dryad.web.oauth2.base.social;

import com.hulk.dryad.manage.security.component.DryadPreAuthenticationChecks;
import com.hulk.dryad.manage.security.util.SecurityMessageSourceUtil;
import com.hulk.dryad.web.oauth2.base.service.DryadUserDetailsService;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsChecker;

/**
 * @author lqx
 * @date 2018/8/5 手机登录校验逻辑 社交登录
 */
@Slf4j
public class SocialAuthenticationProvider implements AuthenticationProvider {

	private MessageSourceAccessor messages = SecurityMessageSourceUtil.getAccessor();

	private UserDetailsChecker detailsChecker = new DryadPreAuthenticationChecks();

	@Getter
	@Setter
	private DryadUserDetailsService userDetailsService;

	@Override
	@SneakyThrows
	public Authentication authenticate(Authentication authentication) {
		SocialAuthenticationToken socialAuthenticationToken = (SocialAuthenticationToken) authentication;
		String principal = socialAuthenticationToken.getPrincipal().toString();
		UserDetails userDetails = userDetailsService.loadUserBySocial(principal);
		if (userDetails == null) {
			log.debug("Authentication failed: no credentials provided");
			throw new BadCredentialsException(messages
					.getMessage("AbstractUserDetailsAuthenticationProvider.noopBindAccount", "Noop Bind Account"));
		}
		/* 检查账号状态*/
		detailsChecker.check(userDetails);
		SocialAuthenticationToken authenticationToken = new SocialAuthenticationToken(userDetails,
				userDetails.getAuthorities());
		authenticationToken.setDetails(socialAuthenticationToken.getDetails());
		return authenticationToken;
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return SocialAuthenticationToken.class.isAssignableFrom(authentication);
	}

}
